package ctu.kfad.run;

import ctu.kfad.run.iterpreter.MethodClassCrate;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;

public class Util {

    public static Method findMethodByName(String name, JavaClass clazz) {
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            if (name.equals(method.getName())) {
                return method;
            }
        }
        throw new RuntimeException(String.format("Method with name '%s' doesn't exist", name));
    }

    /**
     * If you want to search for overridden methods instanceClass should not be null
     *
     * @param name
     * @param instanceClass
     * @param signature
     * @param invokeClass
     * @return
     */
    public static MethodClassCrate findMethodClassByNameAndSignature(String name, JavaClass instanceClass, String signature, JavaClass invokeClass) {
        //TODO private test, so far its implemented only for public

        JavaClass clazzTmp = instanceClass != null ? instanceClass : invokeClass;

        while (clazzTmp != null) {
            Method[] methods = clazzTmp.getMethods();
            for (Method method : methods) {
                if (name.equals(method.getName())) {
                    if (method.getSignature().equals(signature)) {
                        return new MethodClassCrate(method, clazzTmp);
                    }
                }
            }
            try {
                clazzTmp = clazzTmp.getSuperClass();
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(String.format("Method with name '%s' doesn't exist", name));
            }
            if (clazzTmp.getClassName().equals("java.lang.Object")) {
                break;
            }
        }

        throw new RuntimeException(String.format("Method with name '%s' doesn't exist", name));
    }
}
